home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / OpenGL / OPENGL2.EXE / _SETUP.1 / texenv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-21  |  31.3 KB  |  1,159 lines

  1. /*
  2. ** Demonstrates texture environment modes and internal image formats.
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <math.h>
  8. #include <windows.h>
  9. #include <GL/gl.h>
  10. #include <GL/glu.h>
  11.  
  12. char *className = "OpenGL";
  13. char *windowName = "Texture Env Test";
  14. int winX = 0, winY = 0;
  15. int winWidth = 580, winHeight = 720;
  16.  
  17. HDC hDC;
  18. HGLRC hGLRC;
  19. HPALETTE hPalette;
  20. HFONT hFont;
  21.  
  22. GLfloat lightCheck[4] = { 0.7F, 0.7F, 0.7F, 1.0F };
  23. GLfloat darkCheck[4] = { 0.3F, 0.3F, 0.3F, 1.0F };
  24.  
  25. GLfloat labelColor0[4] = { 1.0F, 1.0F, 1.0F, 1.0F };
  26. GLfloat labelColor1[4] = { 1.0F, 1.0F, 0.4F, 1.0F };
  27. GLfloat *labelInfoColor = labelColor0;
  28. GLfloat labelLevelColor0[4] = { 0.8F, 0.8F, 0.1F, 1.0F };
  29. GLfloat labelLevelColor1[4] = { 0.0F, 0.0F, 0.0F, 1.0F };
  30.  
  31. GLboolean highlightFormat = GL_FALSE;
  32. GLboolean colorIndexMode = GL_FALSE;
  33. GLboolean doubleBuffered = GL_FALSE;
  34. GLboolean drawBackground = GL_FALSE;
  35. GLboolean drawBlended = GL_TRUE;
  36. GLboolean drawDithered = GL_TRUE;
  37. GLboolean drawSmooth = GL_FALSE;
  38. GLboolean drawTextured = GL_TRUE;
  39. GLboolean displayLevelInfo = GL_FALSE;
  40. GLboolean filterNearest = GL_TRUE;
  41. GLboolean wrapRepeat = GL_TRUE;
  42. GLboolean perspectiveFastest = GL_TRUE;
  43.  
  44. int textureWidth = 64;
  45. int textureHeight = 64;
  46.  
  47. struct formatInfo {
  48.     GLenum baseFormat;
  49.     GLenum internalFormat;
  50.     char *name;
  51. };
  52.  
  53. #define NUM_LUMINANCE_FORMATS \
  54.         (sizeof(luminanceFormats) / sizeof(luminanceFormats[0]))
  55. struct formatInfo luminanceFormats[] = {
  56.     { GL_LUMINANCE, 1, "LUMINANCE" },
  57.     { GL_LUMINANCE, GL_LUMINANCE4, "LUMINANCE4" },
  58.     { GL_LUMINANCE, GL_LUMINANCE8, "LUMINANCE8" },
  59.     { GL_LUMINANCE, GL_LUMINANCE12, "LUMINANCE12" },
  60.     { GL_LUMINANCE, GL_LUMINANCE16, "LUMINANCE16" },
  61. };
  62.  
  63. #define NUM_ALPHA_FORMATS \
  64.         (sizeof(alphaFormats) / sizeof(alphaFormats[0]))
  65. struct formatInfo alphaFormats[] = {
  66.     { GL_ALPHA, GL_ALPHA, "ALPHA" },
  67.     { GL_ALPHA, GL_ALPHA4, "ALPHA4" },
  68.     { GL_ALPHA, GL_ALPHA8, "ALPHA8" },
  69.     { GL_ALPHA, GL_ALPHA12, "ALPHA12" },
  70.     { GL_ALPHA, GL_ALPHA16, "ALPHA16" },
  71. };
  72.  
  73. #define NUM_INTENSITY_FORMATS \
  74.         (sizeof(intensityFormats) / sizeof(intensityFormats[0]))
  75. struct formatInfo intensityFormats[] = {
  76.     { GL_INTENSITY, GL_INTENSITY, "INTENSITY" },
  77.     { GL_INTENSITY, GL_INTENSITY4, "INTENSITY4" },
  78.     { GL_INTENSITY, GL_INTENSITY8, "INTENSITY8" },
  79.     { GL_INTENSITY, GL_INTENSITY12, "INTENSITY12" },
  80.     { GL_INTENSITY, GL_INTENSITY16, "INTENSITY16" },
  81. };
  82.  
  83. #define NUM_LUMINANCE_ALPHA_FORMATS \
  84.         (sizeof(luminanceAlphaFormats) / sizeof(luminanceAlphaFormats[0]))
  85. struct formatInfo luminanceAlphaFormats[] = {
  86.     { GL_LUMINANCE_ALPHA, 2, "LUMINANCE_ALPHA" },
  87.     { GL_LUMINANCE_ALPHA, GL_LUMINANCE4_ALPHA4, "LUMINANCE4_ALPHA4" },
  88.     { GL_LUMINANCE_ALPHA, GL_LUMINANCE6_ALPHA2, "LUMINANCE6_ALPHA2" },
  89.     { GL_LUMINANCE_ALPHA, GL_LUMINANCE8_ALPHA8, "LUMINANCE8_ALPHA8" },
  90.     { GL_LUMINANCE_ALPHA, GL_LUMINANCE12_ALPHA4, "LUMINANCE12_ALPHA4" },
  91.     { GL_LUMINANCE_ALPHA, GL_LUMINANCE12_ALPHA12, "LUMINANCE12_ALPHA12" },
  92.     { GL_LUMINANCE_ALPHA, GL_LUMINANCE16_ALPHA16, "LUMINANCE16_ALPHA16" },
  93. };
  94.  
  95. #define NUM_RGB_FORMATS \
  96.         (sizeof(rgbFormats) / sizeof(rgbFormats[0]))
  97. struct formatInfo rgbFormats[] = {
  98.     { GL_RGB, 3, "RGB" },
  99.     { GL_RGB, GL_R3_G3_B2, "R3_G3_B2" },
  100.     { GL_RGB, GL_RGB4, "RGB4" },
  101.     { GL_RGB, GL_RGB5, "RGB5" },
  102.     { GL_RGB, GL_RGB8, "RGB8" },
  103.     { GL_RGB, GL_RGB10, "RGB10" },
  104.     { GL_RGB, GL_RGB12, "RGB12" },
  105.     { GL_RGB, GL_RGB16, "RGB16" },
  106. };
  107.  
  108. #define NUM_RGBA_FORMATS \
  109.         (sizeof(rgbaFormats) / sizeof(rgbaFormats[0]))
  110. struct formatInfo rgbaFormats[] = {
  111.     { GL_RGBA, 4, "RGBA" },
  112.     { GL_RGBA, GL_RGBA2, "RGBA2" },
  113.     { GL_RGBA, GL_RGBA4, "RGBA4" },
  114.     { GL_RGBA, GL_RGBA8, "RGBA8" },
  115.     { GL_RGBA, GL_RGBA12, "RGBA12" },
  116.     { GL_RGBA, GL_RGBA16, "RGBA16" },
  117.     { GL_RGBA, GL_RGB5_A1, "RGB5_A1" },
  118.     { GL_RGBA, GL_RGB10_A2, "RGB10_A2" },
  119. };
  120.  
  121. struct baseFormatInfo {
  122.     struct formatInfo *format;
  123.     int current, number;
  124. };
  125.  
  126. #define NUM_BASE_FORMATS \
  127.         (sizeof(baseFormats) / sizeof(baseFormats[0]))
  128. int baseFormat;
  129. struct baseFormatInfo baseFormats[] = {
  130.     { luminanceFormats, 0, NUM_LUMINANCE_FORMATS },
  131.     { alphaFormats, 0, NUM_ALPHA_FORMATS },
  132.     { intensityFormats, 0, NUM_INTENSITY_FORMATS },
  133.     { luminanceAlphaFormats, 0, NUM_LUMINANCE_ALPHA_FORMATS },
  134.     { rgbFormats, 0, NUM_RGB_FORMATS },
  135.     { rgbaFormats, 0, NUM_RGBA_FORMATS },
  136. };
  137.  
  138. #define NUM_ENV_COLORS \
  139.         (sizeof(envColors) / sizeof(envColors[0]))
  140. int envColor;
  141. GLfloat envColors[][4] = {
  142.     { 0.0F, 0.0F, 0.0F, 1.0F },
  143.     { 1.0F, 0.0F, 0.0F, 1.0F },
  144.     { 0.0F, 1.0F, 0.0F, 1.0F },
  145.     { 0.0F, 0.0F, 1.0F, 1.0F },
  146.     { 1.0F, 1.0F, 1.0F, 1.0F },
  147. };
  148.  
  149. struct envModeInfo {
  150.     GLenum mode;
  151.     char *name;
  152. };
  153.  
  154. #define NUM_ENV_MODES \
  155.         (sizeof(envModes) / sizeof(envModes[0]))
  156. struct envModeInfo envModes[] = {
  157.     { GL_REPLACE, "REPLACE" },
  158.     { GL_MODULATE, "MODULATE" },
  159.     { GL_BLEND, "BLEND" },
  160.     { GL_DECAL, "DECAL" },
  161. };
  162.  
  163. /* struct used to manage color ramps */
  164. struct colorIndexState {
  165.     GLfloat amb[3];    /* ambient color / bottom of ramp */
  166.     GLfloat diff[3];    /* diffuse color / middle of ramp */
  167.     GLfloat spec[3];    /* specular color / top of ramp */
  168.     GLfloat ratio;    /* ratio of diffuse to specular in ramp */
  169.     GLint indexes[3];    /* where ramp was placed in palette */
  170. };
  171.  
  172. #define NUM_COLORS (sizeof(colors) / sizeof(colors[0]))
  173. struct colorIndexState colors[] = {
  174.     {
  175.         { 0.0F, 0.0F, 0.0F },
  176.         { 0.2F, 0.6F, 0.4F },
  177.         { 1.0F, 1.0F, 1.0F },
  178.         0.75F, { 0, 0, 0 },
  179.     },
  180.     {
  181.         { 0.0F, 0.05F, 0.05F },
  182.         { 0.9F, 0.0F, 1.0F },
  183.         { 1.0F, 1.0F, 1.0F },
  184.         0.75F, { 0, 0, 0 },
  185.     },
  186.     /*
  187.     {
  188.         { 0.0F, 0.0F, 0.0F },
  189.         { 1.0F, 0.9F, 0.1F },
  190.         { 1.0F, 1.0F, 1.0F },
  191.         0.75F, { 0, 0, 0 },
  192.     },
  193.     {
  194.         { 0.0F, 0.0F, 0.0F },
  195.         { 0.1F, 1.0F, 0.9F },
  196.         { 1.0F, 1.0F, 1.0F },
  197.         0.75F, { 0, 0, 0 },
  198.     },
  199.     */
  200. };
  201.  
  202. void
  203. checkErrors(void)
  204. {
  205.     GLenum error;
  206.  
  207.     while ((error = glGetError()) != GL_NO_ERROR) {
  208.     fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error));
  209.     }
  210. }
  211.  
  212. static void
  213. initializeFont(HDC hDC)
  214. {
  215. #if 0
  216. #define FONTNAME "-*-fixed-medium-r-normal--10-*-*-*-c-60-iso8859-1"
  217. #define FONTBASE 0x1000
  218.  
  219.     XFontStruct *fontStruct;
  220.     int firstRow, lastRow, rows;
  221.  
  222.     if ((fontStruct = XLoadQueryFont(dpy, FONTNAME)) == NULL) {
  223.     fprintf(stderr, "font %s not found\n", FONTNAME);
  224.     exit(EXIT_FAILURE);
  225.     }
  226.     firstRow = fontStruct->min_byte1;
  227.     lastRow = fontStruct->max_byte1;
  228.     rows = lastRow - firstRow + 1;
  229.     
  230.     glXUseXFont(fontStruct->fid, firstRow<<8, rows*256, FONTBASE);
  231.     glListBase(FONTBASE);
  232. #else
  233. #define FONTBASE 0x1000
  234.     /*
  235.     hFont = GetStockObject(SYSTEM_FONT);
  236.     hFont = CreateFont(h, w, esc, orient, weight,
  237.         ital, under, strike, set, out, clip, qual, pitch/fam, face);
  238.     */
  239.     hFont = CreateFont(12, 0, 0, 0, FW_NORMAL,
  240.         FALSE, FALSE, FALSE, ANSI_CHARSET,
  241.         OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DRAFT_QUALITY,
  242.         FIXED_PITCH | FF_MODERN, "Arial");
  243.     if (!hFont) {
  244.     MessageBox(WindowFromDC(hDC),
  245.         "Failed to find acceptable bitmap font.",
  246.         "OpenGL Application Error",
  247.         MB_ICONERROR | MB_OK);
  248.     exit(1);
  249.     }
  250.     (void) SelectObject(hDC, hFont);
  251.     wglUseFontBitmaps(hDC, 0, 255, FONTBASE);
  252.     glListBase(FONTBASE);
  253. #endif
  254. }
  255.  
  256. static void
  257. drawString(char *string, GLfloat x, GLfloat y, GLfloat color[4])
  258. {
  259.     glColor4fv(color);
  260.     glRasterPos2f(x, y);
  261.     glCallLists(strlen(string), GL_BYTE, (GLbyte *) string);
  262. }
  263.  
  264. static void
  265. drawStringOutline(char *string, GLfloat x, GLfloat y,
  266.           GLfloat color[4], GLfloat outline[4])
  267. {
  268.     drawString(string, x-1.0F, y, outline);
  269.     drawString(string, x+1.0F, y, outline);
  270.     drawString(string, x, y-1.0F, outline);
  271.     drawString(string, x, y+1.0F, outline);
  272.     drawString(string, x, y, color);
  273. }
  274.  
  275. static void
  276. begin2D(int width, int height)
  277. {
  278.     glMatrixMode(GL_PROJECTION);
  279.     glPushMatrix();
  280.     glLoadIdentity();
  281.     glOrtho(0.0F, (GLfloat) width, 0.0F, (GLfloat) height, -1.0F, 1.0F);
  282.     glMatrixMode(GL_MODELVIEW);
  283.     glPushMatrix();
  284.     glLoadIdentity();
  285. }
  286.  
  287. static void
  288. end2D(void)
  289. {
  290.     glMatrixMode(GL_PROJECTION);
  291.     glPopMatrix();
  292.     glMatrixMode(GL_MODELVIEW);
  293.     glPopMatrix();
  294. }
  295.  
  296. static void
  297. initialize(HDC hDC)
  298. {
  299.     glMatrixMode(GL_PROJECTION);
  300.     glLoadIdentity();
  301.     glOrtho(-1.5F, 1.5F, -1.5F, 1.5F, -1.5F, 1.5F);
  302.     glMatrixMode(GL_MODELVIEW);
  303.     glLoadIdentity();
  304.  
  305.     glShadeModel(GL_FLAT);
  306. }
  307.  
  308. static void
  309. loadTexture(int width, int height, struct formatInfo *format)
  310. {
  311.     int luminanceSize = 0;
  312.     int alphaSize = 0;
  313.     int rgbSize = 0;
  314.     GLenum textureFormat;
  315.     GLubyte *texImage, *p;
  316.     int elementsPerGroup, elementSize, groupSize, rowSize;
  317.     int i, j;
  318.  
  319.     switch (format->baseFormat) {
  320.     case GL_LUMINANCE:
  321.     case GL_INTENSITY:
  322.     luminanceSize = 1;
  323.     textureFormat = GL_LUMINANCE;
  324.     break;
  325.     case GL_ALPHA:
  326.     alphaSize = 1;
  327.     textureFormat = GL_ALPHA;
  328.     break;
  329.     case GL_LUMINANCE_ALPHA:
  330.     luminanceSize = 1;
  331.     alphaSize = 1;
  332.     textureFormat = GL_LUMINANCE_ALPHA;
  333.     break;
  334.     case GL_RGB:
  335.     rgbSize = 3;
  336.     textureFormat = GL_RGB;
  337.     break;
  338.     case GL_RGBA:
  339.     rgbSize = 3;
  340.     alphaSize = 1;
  341.     textureFormat = GL_RGBA;
  342.     break;
  343.     default:
  344.     fprintf(stderr, "bad internal format info\n");
  345.     return;
  346.     }
  347.  
  348.     elementsPerGroup = luminanceSize + alphaSize + rgbSize;
  349.     elementSize = sizeof(GLubyte);
  350.     groupSize = elementsPerGroup * elementSize;
  351.     rowSize = width * groupSize;
  352.  
  353.     if ((texImage = (GLubyte *) malloc(height * rowSize)) == NULL) {
  354.     fprintf(stderr, "texture malloc failed\n");
  355.     return;
  356.     }
  357.  
  358.     for (i=0; i<height; ++i) {
  359.     p = texImage + i*rowSize;
  360.     for (j=0; j<width; ++j) {
  361.         if (luminanceSize > 0) {
  362.         /*
  363.         ** +-----+-----+
  364.         ** |     |     |
  365.         ** |  W  | LG  |
  366.         ** |     |     |
  367.         ** +-----+-----+
  368.         ** |     |     |
  369.         ** | DG  |  B  |
  370.         ** |     |     |
  371.         ** +-----+-----+
  372.         */
  373.         if (i > height/2) {
  374.            if (j < width/2) {
  375.                p[0] = 0xff;
  376.            } else {
  377.                p[0] = 0xaa;
  378.            }
  379.         } else {
  380.            if (j < width/2) {
  381.                p[0] = 0x55;
  382.            } else {
  383.                p[0] = 0x00;
  384.            }
  385.         }
  386.         p += elementSize;
  387.         }
  388.         if (rgbSize > 0) {
  389.         /*
  390.         ** +-----+-----+
  391.         ** |     |     |
  392.         ** |  R  |  G  |
  393.         ** |     |     |
  394.         ** +-----+-----+
  395.         ** |     |     |
  396.         ** |  Y  |  B  |
  397.         ** |     |     |
  398.         ** +-----+-----+
  399.         */
  400.         if (i > height/2) {
  401.            if (j < width/2) {
  402.                p[0] = 0xff;
  403.                p[1] = 0x00;
  404.                p[2] = 0x00;
  405.            } else {
  406.                p[0] = 0x00;
  407.                p[1] = 0xff;
  408.                p[2] = 0x00;
  409.            }
  410.         } else {
  411.            if (j < width/2) {
  412.                p[0] = 0xff;
  413.                p[1] = 0xff;
  414.                p[2] = 0x00;
  415.            } else {
  416.                p[0] = 0x00;
  417.                p[1] = 0x00;
  418.                p[2] = 0xff;
  419.            }
  420.         }
  421.         p += 3*elementSize;
  422.         }
  423.         if (alphaSize > 0) {
  424.         /*
  425.         ** +-----------+
  426.         ** |     W     |
  427.         ** |  +-----+  |
  428.         ** |  |     |  |
  429.         ** |  |  B  |  |
  430.         ** |  |     |  |
  431.         ** |  +-----+  |
  432.         ** |           |
  433.         ** +-----------+
  434.         */
  435.         int i2 = i - height/2;
  436.         int j2 = j - width/2;
  437.         int h8 = height/8;
  438.         int w8 = width/8;
  439.         if (-h8<=i2 && i2<=h8 && -w8<=j2 && j2<=w8) {
  440.             p[0] = 0x00;
  441.         } else if (-2*h8<=i2 && i2<=2*h8 && -2*w8<=j2 && j2<=2*w8) {
  442.             p[0] = 0x55;
  443.         } else if (-3*h8<=i2 && i2<=3*h8 && -3*w8<=j2 && j2<=3*w8) {
  444.             p[0] = 0xaa;
  445.         } else {
  446.             p[0] = 0xff;
  447.         }
  448.         p += elementSize;
  449.         }
  450.     }
  451.     }
  452.  
  453.     glTexImage2D(GL_TEXTURE_2D, 0,
  454.          format->internalFormat, width, height, 0,
  455.          textureFormat, GL_UNSIGNED_BYTE, texImage);
  456.     
  457.     free(texImage);
  458. }
  459.  
  460. static void
  461. drawCheck(int w, int h, GLfloat lightCheck[4], GLfloat darkCheck[4])
  462. {
  463.     float dw = 2.0F / w;
  464.     float dh = 2.0F / h;
  465.     int i, j;
  466.  
  467.     for (i=0; i<w; ++i) {
  468.     GLfloat x0 = -1.0F + i*dw;
  469.     GLfloat x1 = x0 + dw;
  470.  
  471.     glBegin(GL_QUAD_STRIP);
  472.     for (j=0; j<=h; ++j) {
  473.         GLfloat y = -1.0F + j*dh;
  474.  
  475.         if ((i ^ j) & 1) {
  476.         glColor4fv(lightCheck);
  477.         } else {
  478.         glColor4fv(darkCheck);
  479.         }
  480.  
  481.         glVertex2f(x0, y);
  482.         glVertex2f(x1, y);
  483.     }
  484.     glEnd();
  485.     }
  486. }
  487.  
  488. static void
  489. drawSample(int x, int y, int w, int h,
  490.        struct formatInfo *format, struct envModeInfo *envMode)
  491. {
  492.     glViewport(x, y, w, h);
  493.     glScissor(x, y, w, h);
  494.  
  495.     glClearColor(0.1F, 0.1F, 0.1F, 1.0F);
  496.     glClear(GL_COLOR_BUFFER_BIT);
  497.  
  498.     begin2D(w, h);
  499.     drawString(format->name, 10.0F, h-15.0F, labelInfoColor);
  500.     drawString(envMode->name, 10.0F, 5.0F, labelInfoColor);
  501.     end2D();
  502.  
  503.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, envMode->mode);
  504.     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColors[envColor]);
  505.  
  506.     if (perspectiveFastest) {
  507.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  508.     } else {
  509.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  510.     }
  511.  
  512.     if (filterNearest) {
  513.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  514.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  515.     } else {
  516.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  517.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  518.     }
  519.  
  520.     if (wrapRepeat) {
  521.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  522.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  523.     } else {
  524.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  525.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  526.     }
  527.  
  528.     loadTexture(textureWidth, textureHeight, format);
  529.  
  530.     if (drawBackground) {
  531.     drawCheck(7, 7, lightCheck, darkCheck);
  532.     }
  533.     if (drawBlended) {
  534.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  535.     glEnable(GL_BLEND);
  536.     }
  537.     if (drawSmooth) {
  538.     glShadeModel(GL_SMOOTH);
  539.     }
  540.     if (drawTextured) {
  541.     glEnable(GL_TEXTURE_2D);
  542.     }
  543.  
  544.     glBegin(GL_QUADS);
  545.     glColor4f(1.0F, 0.0F, 0.0F, 1.0F); glTexCoord2f(0.0F, 0.0F);
  546.     glVertex2f(-0.8F, -0.8F);
  547.     glColor4f(0.0F, 1.0F, 0.0F, 1.0F); glTexCoord2f(1.0F, 0.0F);
  548.     glVertex2f( 0.8F, -0.8F);
  549.     glColor4f(0.0F, 0.0F, 1.0F, 1.0F); glTexCoord2f(1.0F, 1.0F);
  550.     glVertex2f( 0.8F,  0.8F);
  551.     glColor4f(1.0F, 1.0F, 1.0F, 1.0F); glTexCoord2f(0.0F, 1.0F);
  552.     glVertex2f(-0.8F,  0.8F);
  553.     glEnd();
  554.  
  555.     glDisable(GL_BLEND);
  556.     glShadeModel(GL_FLAT);
  557.     glDisable(GL_TEXTURE_2D);
  558.  
  559.     if (displayLevelInfo) {
  560.     GLint width, height, border, components;
  561.     GLint redSize, greenSize, blueSize, alphaSize;
  562.     GLint luminanceSize, intensitySize;
  563.     char buf[255];
  564.  
  565.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  566.                  GL_TEXTURE_WIDTH, &width);
  567.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  568.                  GL_TEXTURE_HEIGHT, &height);
  569.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  570.                  GL_TEXTURE_BORDER, &border);
  571.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  572.                  GL_TEXTURE_COMPONENTS, &components);
  573.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  574.                  GL_TEXTURE_RED_SIZE, &redSize);
  575.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  576.                  GL_TEXTURE_GREEN_SIZE, &greenSize);
  577.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  578.                  GL_TEXTURE_BLUE_SIZE, &blueSize);
  579.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  580.                  GL_TEXTURE_ALPHA_SIZE, &alphaSize);
  581.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  582.                  GL_TEXTURE_LUMINANCE_SIZE, &luminanceSize);
  583.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  584.                  GL_TEXTURE_INTENSITY_SIZE, &intensitySize);
  585.  
  586.     begin2D(w, h);
  587.     sprintf(buf, "dimensions: %d x %d", width, height);
  588.     drawStringOutline(buf, 15.0F, h/2.0F+20.0F, labelLevelColor0, labelLevelColor1);
  589.  
  590.     sprintf(buf, "border: %d", border);
  591.     drawStringOutline(buf, 15.0F, h/2.0F+10.0F, labelLevelColor0, labelLevelColor1);
  592.  
  593.     sprintf(buf, "components: 0x%04X", components);
  594.     drawStringOutline(buf, 15.0F, h/2.0F, labelLevelColor0, labelLevelColor1);
  595.  
  596.     sprintf(buf, "sizes:");
  597.     drawStringOutline(buf, 15.0F, h/2.0F-10.0F, labelLevelColor0, labelLevelColor1);
  598.  
  599.     sprintf(buf, "  %d/%d/%d/%d/%d/%d",
  600.         redSize, greenSize, blueSize, alphaSize,
  601.         luminanceSize, intensitySize);
  602.     drawStringOutline(buf, 15.0F, h/2.0F-20.0F, labelLevelColor0, labelLevelColor1);
  603.     end2D();
  604.     }
  605. }
  606.  
  607. static void
  608. redraw(HDC hDC)
  609. {
  610.     int numX = NUM_ENV_MODES, numY = NUM_BASE_FORMATS;
  611.     float xBase = (float) winWidth * 0.01F;
  612.     float xOffset = (winWidth - xBase) / numX;
  613.     float xSize = max(xOffset - xBase, 1);
  614.     float yBase = (float) winHeight * 0.01F;
  615.     float yOffset = (winHeight - yBase) / numY;
  616.     float ySize = max(yOffset - yBase, 1);
  617.     float x, y;
  618.     int i, j;
  619.  
  620.     if (drawDithered) {
  621.     glEnable(GL_DITHER);
  622.     } else {
  623.     glDisable(GL_DITHER);
  624.     }
  625.  
  626.     glDisable(GL_SCISSOR_TEST);
  627.     glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
  628.     glClear(GL_COLOR_BUFFER_BIT);
  629.     glEnable(GL_SCISSOR_TEST);
  630.  
  631.     x = xBase; y = (winHeight - 1) - yOffset;
  632.     for (i=0; i<NUM_BASE_FORMATS; ++i) {
  633.     struct formatInfo *format;
  634.  
  635.     if (highlightFormat && (i == baseFormat)) {
  636.         labelInfoColor = labelColor1;
  637.     } else {
  638.         labelInfoColor = labelColor0;
  639.     }
  640.  
  641.     format = &baseFormats[i].format[baseFormats[i].current];
  642.     for (j=0; j<NUM_ENV_MODES; ++j) {
  643.         struct envModeInfo *envMode;
  644.  
  645.         envMode = &envModes[j];
  646.         drawSample((GLint) x, (GLint) y,
  647.                (GLint) xSize, (GLint) ySize, format, envMode);
  648.         x += xOffset;
  649.     }
  650.     x = xBase; y -= yOffset;
  651.     }
  652.  
  653.     glFlush();
  654.     SwapBuffers(hDC);
  655. }
  656.  
  657. void
  658. resize(HDC hDC)
  659. {
  660.     glViewport(0, 0, winWidth, winHeight);
  661. }
  662.  
  663. /*****************************************************************/
  664.  
  665. /* Main Menu Items */
  666. #define IDM_APPLICATION_EXIT    100
  667. #define IDM_BLEND        101
  668. #define IDM_DITHER        102
  669. #define IDM_BACKGROUND        104
  670. #define IDM_SMOOTH        105
  671. #define IDM_TEXTURE        106
  672. #define IDM_LEVEL_INFO        107
  673.  
  674. /* Perspective Correction Menu Items */
  675. #define IDM_PERSPECTIVE_FASTEST    200
  676. #define IDM_PERSPECTIVE_NICEST    201
  677.  
  678. /* Filter Menu Items */
  679. #define IDM_FILTER_NEAREST    300
  680. #define IDM_FILTER_LINEAR    301
  681.  
  682. /* Wrap Menu Items */
  683. #define IDM_WRAP_REPEAT        400
  684. #define IDM_WRAP_CLAMP        401
  685.  
  686. HMENU hMainPup, hPerspPup, hFilterPup, hWrapPup;
  687.  
  688. void
  689. createPopup(void)
  690. {
  691.     hPerspPup = CreatePopupMenu();
  692.     AppendMenu(hPerspPup, MF_STRING, IDM_PERSPECTIVE_FASTEST, "Fastest");
  693.     AppendMenu(hPerspPup, MF_STRING, IDM_PERSPECTIVE_NICEST, "Nicest");
  694.  
  695.     hFilterPup = CreatePopupMenu();
  696.     AppendMenu(hFilterPup, MF_STRING, IDM_FILTER_NEAREST, "Nearest");
  697.     AppendMenu(hFilterPup, MF_STRING, IDM_FILTER_LINEAR, "Linear");
  698.  
  699.     hWrapPup = CreatePopupMenu();
  700.     AppendMenu(hWrapPup, MF_STRING, IDM_WRAP_REPEAT, "Repeat");
  701.     AppendMenu(hWrapPup, MF_STRING, IDM_WRAP_CLAMP, "Clamp");
  702.  
  703.     hMainPup = CreatePopupMenu();
  704.     AppendMenu(hMainPup, MF_STRING, IDM_BLEND, "Blend");
  705.     AppendMenu(hMainPup, MF_STRING, IDM_DITHER, "Dither");
  706.     AppendMenu(hMainPup, MF_STRING, IDM_TEXTURE, "Texture");
  707.     AppendMenu(hMainPup, MF_STRING, IDM_BACKGROUND, "Background");
  708.     AppendMenu(hMainPup, MF_STRING, IDM_SMOOTH, "Smooth Color");
  709.     AppendMenu(hMainPup, MF_STRING, IDM_LEVEL_INFO, "Level Info");
  710.     AppendMenu(hMainPup, MF_SEPARATOR, 0, NULL);
  711.     AppendMenu(hMainPup, MF_POPUP|MF_STRING, (UINT) hPerspPup, "Perspective");
  712.     AppendMenu(hMainPup, MF_POPUP|MF_STRING, (UINT) hFilterPup, "Filter");
  713.     AppendMenu(hMainPup, MF_POPUP|MF_STRING, (UINT) hWrapPup, "Wrap");
  714.     AppendMenu(hMainPup, MF_SEPARATOR, 0, NULL);
  715.     AppendMenu(hMainPup, MF_STRING, IDM_APPLICATION_EXIT, "Exit");
  716. }
  717.  
  718. void
  719. updatePopup(void)
  720. {
  721.     MENUITEMINFO miinfo;
  722.  
  723.     miinfo.cbSize = sizeof(miinfo);
  724.     miinfo.fMask = MIIM_STATE;
  725.  
  726.     miinfo.fState = perspectiveFastest ? MFS_CHECKED : MFS_UNCHECKED;
  727.     SetMenuItemInfo(hPerspPup, IDM_PERSPECTIVE_FASTEST, FALSE, &miinfo);
  728.     miinfo.fState = !perspectiveFastest ? MFS_CHECKED : MFS_UNCHECKED;
  729.     SetMenuItemInfo(hPerspPup, IDM_PERSPECTIVE_NICEST, FALSE, &miinfo);
  730.  
  731.     miinfo.fState = filterNearest ? MFS_CHECKED : MFS_UNCHECKED;
  732.     SetMenuItemInfo(hFilterPup, IDM_FILTER_NEAREST, FALSE, &miinfo);
  733.     miinfo.fState = !filterNearest ? MFS_CHECKED : MFS_UNCHECKED;
  734.     SetMenuItemInfo(hFilterPup, IDM_FILTER_LINEAR, FALSE, &miinfo);
  735.  
  736.     miinfo.fState = wrapRepeat ? MFS_CHECKED : MFS_UNCHECKED;
  737.     SetMenuItemInfo(hWrapPup, IDM_WRAP_REPEAT, FALSE, &miinfo);
  738.     miinfo.fState = !wrapRepeat ? MFS_CHECKED : MFS_UNCHECKED;
  739.     SetMenuItemInfo(hWrapPup, IDM_WRAP_CLAMP, FALSE, &miinfo);
  740.  
  741.     miinfo.fState = drawBlended ? MFS_CHECKED : MFS_UNCHECKED;
  742.     SetMenuItemInfo(hMainPup, IDM_BLEND, FALSE, &miinfo);
  743.     miinfo.fState = drawDithered ? MFS_CHECKED : MFS_UNCHECKED;
  744.     SetMenuItemInfo(hMainPup, IDM_DITHER, FALSE, &miinfo);
  745.     miinfo.fState = drawBackground ? MFS_CHECKED : MFS_UNCHECKED;
  746.     SetMenuItemInfo(hMainPup, IDM_BACKGROUND, FALSE, &miinfo);
  747.     miinfo.fState = drawSmooth ? MFS_CHECKED : MFS_UNCHECKED;
  748.     SetMenuItemInfo(hMainPup, IDM_SMOOTH, FALSE, &miinfo);
  749.     miinfo.fState = drawTextured ? MFS_CHECKED : MFS_UNCHECKED;
  750.     SetMenuItemInfo(hMainPup, IDM_TEXTURE, FALSE, &miinfo);
  751.     miinfo.fState = displayLevelInfo ? MFS_CHECKED : MFS_UNCHECKED;
  752.     SetMenuItemInfo(hMainPup, IDM_LEVEL_INFO, FALSE, &miinfo);
  753. }
  754.  
  755. void
  756. setupPalette(HDC hDC)
  757. {
  758.     PIXELFORMATDESCRIPTOR pfd;
  759.     LOGPALETTE* pPal;
  760.     int pixelFormat = GetPixelFormat(hDC);
  761.     int paletteSize;
  762.  
  763.     (void) DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  764.     if (!(pfd.dwFlags & PFD_NEED_PALETTE)) {
  765.     return;
  766.     }
  767.  
  768.     paletteSize = 1 << pfd.cColorBits;
  769.     pPal = (LOGPALETTE*)
  770.     malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
  771.     memset(pPal, 0, sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
  772.     pPal->palVersion = 0x300;
  773.     pPal->palNumEntries = paletteSize;
  774.  
  775.     /* start with a copy of the current system palette */
  776.     (void) GetSystemPaletteEntries(hDC, 0, paletteSize, &pPal->palPalEntry[0]);
  777.  
  778.     if (pfd.iPixelType == PFD_TYPE_RGBA) {
  779.     /* fill in an RGBA color palette */
  780.     int redMask = (1 << pfd.cRedBits) - 1;
  781.     int greenMask = (1 << pfd.cGreenBits) - 1;
  782.     int blueMask = (1 << pfd.cBlueBits) - 1;
  783.     int i;
  784.  
  785.     for (i=10; i<paletteSize-10; ++i) {
  786.         pPal->palPalEntry[i].peRed =
  787.             (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
  788.         pPal->palPalEntry[i].peGreen =
  789.             (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
  790.         pPal->palPalEntry[i].peBlue =
  791.             (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
  792.         pPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
  793.     }
  794.     } else {
  795.     /* fill in a Color Index ramp color palette */
  796.     int numRamps = NUM_COLORS;
  797.     int rampSize = (paletteSize - 10) / numRamps;
  798.     int i, r;
  799.  
  800.     for (r=0; r<numRamps; ++r) {
  801.         int rampBase = r * rampSize + 10;
  802.         PALETTEENTRY *pe = &pPal->palPalEntry[rampBase];
  803.         int diffSize = (int) (rampSize * colors[r].ratio);
  804.         int specSize = rampSize - diffSize;
  805.  
  806.         for (i=0; i<rampSize; ++i) {
  807.         GLfloat *c0, *c1;
  808.         GLint a;
  809.  
  810.         if (i < diffSize) {
  811.             c0 = colors[r].amb;
  812.             c1 = colors[r].diff;
  813.             a = (i * 255) / (diffSize - 1);
  814.         } else {
  815.             c0 = colors[r].diff;
  816.             c1 = colors[r].spec;
  817.             a = ((i - diffSize) * 255) / (specSize - 1);
  818.         }
  819.  
  820.         pe[i].peRed = (BYTE) (a * (c1[0] - c0[0]) + 255 * c0[0]);
  821.         pe[i].peGreen = (BYTE) (a * (c1[1] - c0[1]) + 255 * c0[1]);
  822.         pe[i].peBlue = (BYTE) (a * (c1[2] - c0[2]) + 255 * c0[2]);
  823.         pe[i].peFlags = PC_NOCOLLAPSE;
  824.         }
  825.  
  826.         colors[r].indexes[0] = rampBase;
  827.         colors[r].indexes[1] = rampBase + (diffSize-1);
  828.         colors[r].indexes[2] = rampBase + (rampSize-1);
  829.     }
  830.     }
  831.  
  832.     hPalette = CreatePalette(pPal);
  833.     free(pPal);
  834.  
  835.     if (hPalette) {
  836.     SelectPalette(hDC, hPalette, FALSE);
  837.     RealizePalette(hDC);
  838.     }
  839. }
  840.  
  841. void
  842. setupPixelFormat(HDC hDC)
  843. {
  844.     PIXELFORMATDESCRIPTOR pfd = {
  845.     sizeof(PIXELFORMATDESCRIPTOR),    /* size of this pfd */
  846.     1,                /* version num */
  847.     PFD_DRAW_TO_WINDOW |        /* support window */
  848.     PFD_SUPPORT_OPENGL |        /* support OpenGL */
  849.     PFD_DOUBLEBUFFER,        /* support double buffering */
  850.     0,                /* color type (filled below) */
  851.     8,                /* 8-bit color depth */
  852.     0, 0, 0, 0, 0, 0,        /* color bits (ignored) */
  853.     0,                /* no alpha buffer */
  854.     0,                /* alpha bits (ignored) */
  855.     0,                /* no accumulation buffer */
  856.     0, 0, 0, 0,            /* accum bits (ignored) */
  857.     16,                /* 16-bit depth buffer */
  858.     0,                /* no stencil buffer */
  859.     0,                /* no auxiliary buffers */
  860.     PFD_MAIN_PLANE,            /* main layer */
  861.     0,                /* reserved */
  862.     0, 0, 0,            /* no layer, visible, damage masks */
  863.     };
  864.     int SelectedPixelFormat;
  865.     BOOL retVal;
  866.  
  867.     if (0 && GetDeviceCaps(hDC, BITSPIXEL) == 8) {
  868.     colorIndexMode = TRUE;
  869.     pfd.iPixelType = PFD_TYPE_COLORINDEX;
  870.     } else {
  871.     colorIndexMode = FALSE;
  872.     pfd.iPixelType = PFD_TYPE_RGBA;
  873.     }
  874.  
  875.     SelectedPixelFormat = ChoosePixelFormat(hDC, &pfd);
  876.     if (SelectedPixelFormat == 0) {
  877.     MessageBox(WindowFromDC(hDC),
  878.         "Failed to find acceptable pixel format.",
  879.         "OpenGL Application Error",
  880.         MB_ICONERROR | MB_OK);
  881.     exit(1);
  882.     }
  883.  
  884.     retVal = SetPixelFormat(hDC, SelectedPixelFormat, &pfd);
  885.     if (retVal != TRUE) {
  886.     MessageBox(WindowFromDC(hDC),
  887.         "Failed to set pixel format.",
  888.         "OpenGL Application Error",
  889.         MB_ICONERROR | MB_OK);
  890.     exit(1);
  891.     }
  892. }
  893.  
  894. LRESULT APIENTRY
  895. WndProc(
  896.     HWND hWnd,
  897.     UINT message,
  898.     WPARAM wParam,
  899.     LPARAM lParam)
  900. {
  901.     switch (message) {
  902.     case WM_CREATE:
  903.     hDC = GetDC(hWnd);
  904.     setupPixelFormat(hDC);
  905.     setupPalette(hDC);
  906.     hGLRC = wglCreateContext(hDC);
  907.     if (hGLRC) {
  908.         wglMakeCurrent(hDC, hGLRC);
  909.         initializeFont(hDC);
  910.         initialize(hDC);
  911.     }
  912.     return 0;
  913.     case WM_DESTROY:
  914.     if (hGLRC) {
  915.         wglMakeCurrent(NULL, NULL);
  916.         wglDeleteContext(hGLRC);
  917.     }
  918.     ReleaseDC(hWnd, hDC);
  919.     PostQuitMessage(0);
  920.     return 0;
  921.     case WM_SIZE:
  922.     if (hGLRC) {
  923.         winWidth = (int) LOWORD(lParam);
  924.         winHeight = (int) HIWORD(lParam);
  925.         resize(hDC);
  926.         return 0;
  927.     }
  928.     break;
  929.     case WM_PALETTECHANGED:
  930.     if (hPalette != NULL && (HWND) wParam != hWnd) {
  931.         UnrealizeObject(hPalette);
  932.         SelectPalette(hDC, hPalette, FALSE);
  933.         RealizePalette(hDC);
  934.         if (hGLRC) redraw(hDC);
  935.         return 0;
  936.     }
  937.     break;
  938.     case WM_QUERYNEWPALETTE:
  939.     if (hPalette != NULL) {
  940.         UnrealizeObject(hPalette);
  941.         SelectPalette(hDC, hPalette, FALSE);
  942.         RealizePalette(hDC);
  943.         if (hGLRC) redraw(hDC);
  944.         return TRUE;
  945.     }
  946.     break;
  947.     case WM_PAINT:
  948.     if (hGLRC) {
  949.         PAINTSTRUCT ps;
  950.         HDC hPaintDC = BeginPaint(hWnd, &ps);
  951.         redraw(hDC);
  952.         EndPaint(hWnd, &ps);
  953.         return 0;
  954.     }
  955.     case WM_CHAR:
  956.     switch ((int)wParam) {
  957.     case 'b':
  958.         SendMessage(hWnd, WM_COMMAND, IDM_BLEND, 0);
  959.         break;
  960.     case 'd':
  961.         SendMessage(hWnd, WM_COMMAND, IDM_DITHER, 0);
  962.         break;
  963.     case 'g':
  964.         SendMessage(hWnd, WM_COMMAND, IDM_BACKGROUND, 0);
  965.         break;
  966.     case 's':
  967.         SendMessage(hWnd, WM_COMMAND, IDM_SMOOTH, 0);
  968.         break;
  969.     case 't':
  970.         SendMessage(hWnd, WM_COMMAND, IDM_TEXTURE, 0);
  971.         break;
  972.     case 'i':
  973.         SendMessage(hWnd, WM_COMMAND, IDM_LEVEL_INFO, 0);
  974.         break;
  975.     case 'p':
  976.         if (perspectiveFastest) {
  977.         SendMessage(hWnd, WM_COMMAND, IDM_PERSPECTIVE_NICEST, 0);
  978.         } else {
  979.         SendMessage(hWnd, WM_COMMAND, IDM_PERSPECTIVE_FASTEST, 0);
  980.         }
  981.         break;
  982.     case 'f':
  983.         if (filterNearest) {
  984.         SendMessage(hWnd, WM_COMMAND, IDM_FILTER_LINEAR, 0);
  985.         } else {
  986.         SendMessage(hWnd, WM_COMMAND, IDM_FILTER_NEAREST, 0);
  987.         }
  988.         break;
  989.     case 'w':
  990.         if (wrapRepeat) {
  991.         SendMessage(hWnd, WM_COMMAND, IDM_WRAP_CLAMP, 0);
  992.         } else {
  993.         SendMessage(hWnd, WM_COMMAND, IDM_WRAP_REPEAT, 0);
  994.         }
  995.         break;
  996.     case 'c':
  997.         envColor = ++envColor % NUM_ENV_COLORS;
  998.         break;
  999.     default:
  1000.         break;
  1001.     }
  1002.     if (hGLRC) redraw(hDC);
  1003.     return 0;
  1004.     case WM_KEYDOWN:
  1005.     switch ((int)wParam) {
  1006.     case VK_ESCAPE:
  1007.         DestroyWindow(hWnd);
  1008.         break;
  1009.     case VK_SPACE:
  1010.         highlightFormat = !highlightFormat;
  1011.         break;
  1012.     case VK_DOWN:
  1013.         if (highlightFormat) {
  1014.         if (++baseFormat > NUM_BASE_FORMATS-1) baseFormat = 0;
  1015.         }
  1016.         break;
  1017.     case VK_UP:
  1018.         if (highlightFormat) {
  1019.         if (--baseFormat < 0) baseFormat = NUM_BASE_FORMATS-1;
  1020.         }
  1021.         break;
  1022.     case VK_LEFT:
  1023.         if (highlightFormat) {
  1024.         --baseFormats[baseFormat].current;
  1025.         if (baseFormats[baseFormat].current < 0)
  1026.             baseFormats[baseFormat].current =
  1027.             baseFormats[baseFormat].number-1;
  1028.         }
  1029.         break;
  1030.     case VK_RIGHT:
  1031.         if (highlightFormat) {
  1032.         ++baseFormats[baseFormat].current;
  1033.         if (baseFormats[baseFormat].current > baseFormats[baseFormat].number-1)
  1034.             baseFormats[baseFormat].current = 0;
  1035.         }
  1036.         break;
  1037.     default:
  1038.         break;
  1039.     }
  1040.     if (hGLRC) redraw(hDC);
  1041.     return 0;
  1042.     case WM_COMMAND:
  1043.     switch (LOWORD(wParam)) {
  1044.     case IDM_APPLICATION_EXIT:
  1045.         DestroyWindow(hWnd);
  1046.         break;
  1047.     case IDM_BLEND:
  1048.         drawBlended = !drawBlended;
  1049.         break;
  1050.     case IDM_DITHER:
  1051.         drawDithered = !drawDithered;
  1052.         break;
  1053.     case IDM_BACKGROUND:
  1054.         drawBackground = !drawBackground;
  1055.         break;
  1056.     case IDM_SMOOTH:
  1057.         drawSmooth = !drawSmooth;
  1058.         break;
  1059.     case IDM_TEXTURE:
  1060.         drawTextured = !drawTextured;
  1061.         break;
  1062.     case IDM_LEVEL_INFO:
  1063.         displayLevelInfo = !displayLevelInfo;
  1064.         break;
  1065.     case IDM_PERSPECTIVE_FASTEST:
  1066.         perspectiveFastest = GL_TRUE;
  1067.         break;
  1068.     case IDM_PERSPECTIVE_NICEST:
  1069.         perspectiveFastest = GL_FALSE;
  1070.         break;
  1071.     case IDM_FILTER_NEAREST:
  1072.         filterNearest = GL_TRUE;
  1073.         break;
  1074.     case IDM_FILTER_LINEAR:
  1075.         filterNearest = GL_FALSE;
  1076.         break;
  1077.     case IDM_WRAP_REPEAT:
  1078.         wrapRepeat = GL_TRUE;
  1079.         break;
  1080.     case IDM_WRAP_CLAMP:
  1081.         wrapRepeat = GL_FALSE;
  1082.         break;
  1083.     default:
  1084.         /* unknown command -- do nothing */
  1085.         break;
  1086.     }
  1087.     updatePopup();
  1088.     if (hGLRC) redraw(hDC);
  1089.     break;
  1090.     case WM_CONTEXTMENU:
  1091.     TrackPopupMenu(hMainPup, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
  1092.             LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
  1093.     break;
  1094.     default:
  1095.     break;
  1096.     }
  1097.  
  1098.     /* Deal with any unprocessed messages */
  1099.     return DefWindowProc(hWnd, message, wParam, lParam);
  1100. }
  1101.  
  1102. int APIENTRY
  1103. WinMain(
  1104.     HINSTANCE hCurrentInst,
  1105.     HINSTANCE hPreviousInst,
  1106.     LPSTR lpszCmdLine,
  1107.     int nCmdShow)
  1108. {
  1109.     WNDCLASS wndClass;
  1110.     HWND hWnd;
  1111.     MSG msg;
  1112.  
  1113.     /* Define and register the window class */
  1114.     wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  1115.     wndClass.lpfnWndProc = WndProc;
  1116.     wndClass.cbClsExtra = 0;
  1117.     wndClass.cbWndExtra = 0;
  1118.     wndClass.hInstance = hCurrentInst;
  1119.     wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  1120.     wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
  1121.     wndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
  1122.     wndClass.lpszMenuName = NULL;
  1123.     wndClass.lpszClassName = className;
  1124.     RegisterClass(&wndClass);
  1125.  
  1126.     /* Create a window of the previously defined class */
  1127.     hWnd = CreateWindow(
  1128.     className,        /* Window class's name */
  1129.     windowName,        /* Title bar text */
  1130.     WS_OVERLAPPEDWINDOW |    /* The window's style */
  1131.     WS_CLIPCHILDREN |
  1132.     WS_CLIPSIBLINGS,
  1133.     winX, winY,        /* Position */
  1134.     winWidth, winHeight,    /* Size */
  1135.     NULL,            /* Parent window's handle */
  1136.     NULL,            /* Menu handle */
  1137.     hCurrentInst,        /* Instance handle */
  1138.     NULL);            /* No additional data */
  1139.  
  1140.     /* Map the window to the screen */
  1141.     ShowWindow(hWnd, nCmdShow);
  1142.  
  1143.     /* Force the window to repaint itself */
  1144.     UpdateWindow(hWnd);
  1145.  
  1146.     createPopup();
  1147.     updatePopup();
  1148.  
  1149.     /* Message loop */
  1150.     while (GetMessage(&msg, NULL, 0, 0) == TRUE) {
  1151.     TranslateMessage(&msg);
  1152.     DispatchMessage(&msg);
  1153.     }
  1154.  
  1155.     return msg.wParam;
  1156. }
  1157.  
  1158. 
  1159.